# N, V = map(int, input().split())
# # dp[N][V]
#
# dp = [[0] * (V + 1) for i in range(N + 1)]
#
# # dp[i][j]表示前i件物品，在体积为j时的最大价值
# for i in range(1, N + 1):
#     wi, vi = map(int, input().split())
#     for j in range(V + 1):
#         if j < wi:
#             dp[i][j] = dp[i - 1][j]
#         else:
#             dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - wi] + vi)
#
# print(dp[N][V])
#
# # 优化：滚动数组
# # 每一行的更新只于上一行有关
# n, V = map(int, input().split())
#
# dp = [[0] * (V + 1) for i in range(2)]
#
# # dp[i][j]表示前i件物品，在体积为j时的最大价值
# for i in range(1, n + 1):
#     wi, vi = map(int, input().split())
#     for j in range(V + 1):
#         if j < wi:
#             dp[i % 2][j] = dp[(i - 1) % 2][j]
#         else:
#             dp[i % 2][j] = max(dp[(i - 1) % 2][j], dp[(i - 1) % 2][j - wi] + vi)
#
# print(dp[n % 2][V])


n,V=map(int,input().split())
dp=[0]*(V+1)
#[0, 6, 6, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11]
for i in range(1,n+1):
    wi,vi=map(int,input().split())
    # 必须从大到小，避免被覆盖
    for j in range(V,wi-1,-1):
        dp[j]=max(dp[j],dp[j-wi]+vi)
print(dp[V])